package com.lfy.aop;

import com.lfy.cache.FileShareCache;
import com.lfy.modules.common.anno.CheckShareToken;
import com.lfy.modules.common.domain.R;
import com.lfy.modules.common.utils.SpElUtils;
import io.jsonwebtoken.lang.Collections;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;

import javax.xml.crypto.dsig.SignatureMethod;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Set;

@Aspect
@Component
@Slf4j
public class CheckShareTokenAspect {
    @Pointcut("@annotation(com.lfy.modules.common.anno.CheckShareToken)")
    public void checkShareToken() {
    }
    @SneakyThrows
    @Around("checkShareToken()")
    public Object around(ProceedingJoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        CheckShareToken shareToken = AnnotationUtils.getAnnotation(method, CheckShareToken.class);
        String el = shareToken.value();
        String token = shareToken.token();
        String parentId = shareToken.parentId();
        Object[] args = joinPoint.getArgs();

        //解析spel表达式
        String parseSpEl =SpElUtils.parseSpEl(method,args, parentId);

        if(StringUtils.isBlank(parseSpEl)){
                parseSpEl = SpElUtils.parseSpEl(method, args, el);
            }


        //解析token
        String parseToken = SpElUtils.parseSpEl(method, args, token);
        if(StringUtils.isBlank(parseSpEl) || StringUtils.isBlank(parseToken)){
            return R.error("禁止越权提取文件");
        }

        Set<Long> set = FileShareCache.get(parseToken);
        if(Collections.isEmpty(set) || !set.contains(Long.parseLong(parseSpEl))){
            return R.error("身份验证失败，请重新提取文件");
        }



        return joinPoint.proceed();
    }
}
